package com.i2works.smartluolong.web.controller.user;


import com.i2works.smartluolong.utils.base.MsgEnum;
import com.i2works.smartluolong.utils.common.BaseUtils;
import com.i2works.smartluolong.utils.common.SmsUtil;
import com.i2works.smartluolong.utils.common.VerifyCodeUtil;
import com.i2works.smartluolong.utils.entity.R;
import com.i2works.smartluolong.utils.entity.Result;
import com.i2works.smartluolong.utils.exception.ServiceException;
import com.i2works.smartluolong.utils.redis.RedisSessionDAO;
import com.i2works.smartluolong.utils.shiro.SmartLuoLongToken;
import com.i2works.smartluolong.utils.web.HtmlConstant;
import com.i2works.smartluolong.web.entity.user.UserAccountDO;
import com.i2works.smartluolong.web.entity.user.UserAccountQuery;
import com.i2works.smartluolong.web.entity.user.UserLoginVO;
import com.i2works.smartluolong.web.service.user.IUserAccountService;
import com.i2works.smartluolong.web.utils.BaseModule;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 废弃用第三方登陆
 *
 * 用户账号控制层
 * @author koal <koal@vip.qq.com>
 * @date 2017/9/27 20:06
 */

@Controller
@RequestMapping("/user")
public class UserAccountController extends BaseModule {
    /**
     * 通用错误键名
     */
    public final static String MESSAGE_CODE = "messageCode";

    /*
    *//**
     * 跳转网址
     *//*
    private static String REDIRECT_URL = null;
    *//**
     * 用户账号
     *//*
    private final IUserAccountService userAccountService;

    *//**
     * 发送短信
     *//*
    private final SmsUtil smsUtil;

    *//**
     * redis
     *//*
    private final RedisSessionDAO redisSessionDAO;

    @Autowired
    public UserAccountController(IUserAccountService userAccountService, SmsUtil smsUtil, RedisSessionDAO redisSessionDAO) {
        this.userAccountService = userAccountService;
        this.smsUtil = smsUtil;
        this.redisSessionDAO = redisSessionDAO;
    }


    *//**
     * 用户登录页面
     *//*
    @GetMapping("/login")
    public String login(@RequestParam(value = MESSAGE_CODE, required = false) String messageCode, Model model, HttpServletRequest request) {
        if (StringUtils.isNotBlank(messageCode)) {
            model.addAttribute(MESSAGE_CODE, messageCode);
        }
//        return isLogin(request, "/user/login");
        return "/user/login";
    }

    *//**
     * 用户登录方法
     *//*
    @PostMapping("/login")
    @ResponseBody
    public Result login(@ModelAttribute UserLoginVO userLogin, HttpServletRequest request, RedirectAttributes redirect) {
        try {

            //判断账号密码是否为空
            if (StringUtils.isAnyBlank(userLogin.getUserName(), userLogin.getPassword())) {
                return R.error(MsgEnum.ACCESS_EMPTY.getMsg());
            }

            //图片验证码
            Result result = checkImgCode(request.getRequestedSessionId(), userLogin.getImgCode());
            if (!result.getSuccess()) {
                return result;
            }

            //获取用户
            Subject subject = SecurityUtils.getSubject();
            //判断是否授权和记住登录信息
            if (subject.isAuthenticated() || subject.isRemembered()) {
                if (StringUtils.isNotBlank(REDIRECT_URL)) {
                    return R.success(MsgEnum.ACCESS_LOGIN_SUCCESS.getMsg(), HtmlConstant.REDIRECT + REDIRECT_URL);
                } else {
                    return R.success(MsgEnum.ACCESS_LOGIN_SUCCESS.getMsg(), "/user/index");
                }
            }
            UserAccountDO accountDO = userAccountService.queryLoginUser(userLogin.getUserName());
            if (null == accountDO) {
                //账号不存在
                return R.error(MsgEnum.ACCESS_UNKNOW.getMsg());
            }
            UsernamePasswordToken token = new UsernamePasswordToken(accountDO.getUserName(), userLogin.getPassword(), true);
            //登录
            subject.login(token);
            // 设置登陆信息
            if (getLoginUser() != null) {
                UserAccountDO userAccount = getLoginUser();
                userAccount.setLoginIp(BaseUtils.getIP(request));
                userAccount.setLoginTime(new Date());
                userAccountService.update(userAccount);
                //用于登录后跳转到之前网址
                return R.success(MsgEnum.ACCESS_LOGIN_SUCCESS.getMsg(), "/user/index");
            } else {
                //登录异常
                return R.error(MsgEnum.LOGIN_FAILED.getMsg());
            }
        } catch (ExcessiveAttemptsException e) {
            //账号密码输错次数达到上限
            return R.error(MsgEnum.ACCESS_LOCKED.getMsg());
        } catch (UnknownAccountException e) {
            //账号或密码为空
            return R.error(MsgEnum.ACCESS_UNKNOW.getMsg());
        } catch (IncorrectCredentialsException e) {
            //账号错误
            return R.error(MsgEnum.ACCESS_ERROR.getMsg());
        } catch (LockedAccountException e) {
            //账号已被停用
            return R.error(MsgEnum.ACCESS_INVALID.getMsg());
        } catch (Exception e) {
            e.printStackTrace();
            //登录异常
            logger.error("用户登录异常:" + e.getMessage());
            return R.error(MsgEnum.LOGIN_FAILED.getMsg());
        }
    }


    *//**
     * ukey登陆页面
     *//*
    @PostMapping("/ukeyLogin")
    @ResponseBody
    public Result ukeyLogin(@RequestParam(value = "ukey", required = false) String ukey, HttpServletRequest request, Model model) {
        try {
            //判断ukey
            if (StringUtils.isBlank(ukey)) {
                return R.error(MsgEnum.ATTRS_EMPTY.getMsg());
            }
            //获取用户
            Subject subject = SecurityUtils.getSubject();
            UserAccountDO userLogin = userAccountService.queryLoginUser(ukey);
            if (userLogin == null) {
                //账号不存在
                return R.error(MsgEnum.ACCESS_UNKNOW.getMsg());
            }
            SmartLuoLongToken token = new SmartLuoLongToken(userLogin.getUserName());
            //登录
            subject.login(token);
            // 设置登陆信息
            return R.success(MsgEnum.ACCESS_LOGIN_SUCCESS.getMsg(), "/user/index");
        } catch (ExcessiveAttemptsException e) {
            //账号密码输错次数达到上限
            return R.error(MsgEnum.ACCESS_LOCKED.getMsg());
        } catch (UnknownAccountException e) {
            //账号或密码为空
            return R.error(MsgEnum.ACCESS_UNKNOW.getMsg());
        } catch (IncorrectCredentialsException e) {
            //账号错误
            return R.error(MsgEnum.ACCESS_ERROR.getMsg());
        } catch (LockedAccountException e) {
            //账号已被停用
            return R.error(MsgEnum.ACCESS_INVALID.getMsg());
        } catch (Exception e) {
            //登录异常
            logger.error("用户登录异常:" + e.getMessage());
            return R.error(MsgEnum.LOGIN_FAILED.getMsg());
        }
    }
    


    *//**
     * 用户注册页面
     *//*
    @GetMapping(value = {"/register", "/register?operatorId={operatorId:\\d+}"})
    public String register(
            @RequestParam(value = MESSAGE_CODE, required = false) String messageCode,
            @RequestParam(value = "operatorId",required = false) Integer operatorId,
            Model model, HttpServletRequest request) {
        if (StringUtils.isNotBlank(messageCode)) {
            model.addAttribute(MESSAGE_CODE, messageCode);
        }
        //判断operatorId
        if (operatorId != null) {
            redisSessionDAO.set("user_regedit_by_operatorid", operatorId);
            model.addAttribute("operatorId", operatorId);
        }
        return "/user/register";
    }


    *//**
     * 用户注册方法
     *//*
    @PostMapping("/register")
    @ResponseBody
    public Result register(@ModelAttribute UserLoginVO userLoginVO, HttpServletRequest request, RedirectAttributes redirect) {
        try {
            //实体
            if (null == userLoginVO) {
                return R.error(MsgEnum.ATTRS_EMPTY.getMsg());
            }

            //手机号
            if (StringUtils.isBlank(userLoginVO.getPhone())) {
                return R.error(MsgEnum.ACCESS_PHONE_NULL.getMsg());
            }

            //账号密码
            if (StringUtils.isAnyBlank(userLoginVO.getUserName(), userLoginVO.getPassword())) {
                return R.error(MsgEnum.ACCESS_USERPHOME_EMPTY.getMsg());
            }

            //两次密码对比
            if (StringUtils.isNotBlank(userLoginVO.getConfirmPassword())) {
                if (!StringUtils.equalsIgnoreCase(userLoginVO.getPassword(), userLoginVO.getConfirmPassword())) {
                    return R.error(MsgEnum.ACCESS_CONFIRMPASSWORD_ERROR.getMsg());
                }
            }

            //短信验证码
            Result result = checkSmsCode(userLoginVO.getPhone(), userLoginVO.getCode());
            if (!result.getSuccess()) {
                return result;
            }

            //判断验证码和用户信息
            UserAccountQuery userAccountQuery = new UserAccountQuery();
            userAccountQuery.setUserName(userLoginVO.getUserName());
            userAccountQuery.setPhone(userLoginVO.getPhone());
            int queryCheck = userAccountService.queryCheck(userAccountQuery);
            if (queryCheck > 0) {
                return R.error(MsgEnum.ACCESS_USERPHOME_KNOW.getMsg());
            } else {
                //注册
                userLoginVO.setCreateName(userLoginVO.getUserName());
                userLoginVO.setUpdateName(userLoginVO.getUserName());
                userLoginVO.setLoginIp(BaseUtils.getIP(request));
                Integer saveStatus = userAccountService.saveRegisterUser(userLoginVO);

                if (saveStatus > 0) {
                    //获取subject
                    Subject subject = SecurityUtils.getSubject();
                    UsernamePasswordToken token = new UsernamePasswordToken(userLoginVO.getUserName(), userLoginVO.getConfirmPassword(), true);
                    //登录
                    subject.login(token);
                    //账号注册成功，判断当前用户的代办人信息
                    if (userLoginVO.getOperatorId() != null) {
                        //添加用户 与 代办人 关系表
                        //Integer operatorId = userLoginVO.getOperatorId();
                        //Integer userId = userLoginVO.getId();
                    }
                    //用于登录后跳转到之前网址
                    return R.success(MsgEnum.ACCESS_REG_SUCCESS.getMsg(), "/user/index");
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            return R.error(MsgEnum.REGIST_FAILED.getMsg());
        }
        return R.error(MsgEnum.REGIST_FAILED.getMsg());
    }

    *//**
     * 找回密码
     *//*
    @GetMapping("/resetPassword")
    public String resetPassword() {
        return "/user/resetPassword";
    }


    *//**
     * 找回密码方法
     *//*
    @PostMapping("/resetPassword")
    @ResponseBody
    public Result resetPassword(@ModelAttribute UserLoginVO userLoginVO) {
        //实体
        if (null == userLoginVO) {
            return R.error(MsgEnum.ATTRS_EMPTY.getMsg());
        }

        //判断手机号密码是否为空
        if (StringUtils.isAnyBlank(userLoginVO.getPhone(), userLoginVO.getPassword())) {
            return R.error(MsgEnum.ACCESS_PHOMEPASSWORD_EMPTY.getMsg());
        }

        //短信验证码
        Result result = checkSmsCode(userLoginVO.getPhone(), userLoginVO.getCode());
        if (!result.getSuccess()) {
            return result;
        }

        try {
            //判断账号是否存在
            UserAccountQuery userAccountQuery = new UserAccountQuery();
            userAccountQuery.setPhone(userLoginVO.getPhone());
            int queryCheck = userAccountService.queryCheck(userAccountQuery);
            if (queryCheck > 0) {
                UserAccountDO userAccountDO = new UserAccountDO();
                userAccountDO.setPhone(userLoginVO.getPhone());
                userAccountDO.setPassword(userLoginVO.getPassword());
                userAccountService.updatePassword(userAccountDO);
                return R.success(MsgEnum.ACCESS_UPDATE_PASSWORD_SUCCESS.getMsg());
            } else {
                return R.error(MsgEnum.ACCESS_PHONE_NOKNOW.getMsg());
            }
        } catch (ServiceException e) {
            logger.error("登录异常：" + e.getMessage());
            return R.error(MsgEnum.ACCESS_UPDATE_PASSWORD_FAIL.getMsg());
        }
    }

    *//**
     * 账号元素占用检测
     *
     * @param checkType 1账号,2邮箱,3手机号，0全部
     * @param keyword   账号/邮箱/手机号
     * @return Boolean 存在返回false,不存在返回true
     *//*
    @PostMapping(value = {"/check", "/check/{checkType}"})
    @ResponseBody
    public Boolean check(@PathVariable Integer checkType, @RequestParam(required = false, value = "param") String keyword) {
        try {
            checkType = checkType == null ? 0 : checkType;
            if (StringUtils.isNotBlank(keyword)) {
                UserAccountQuery userQuery = new UserAccountQuery();
                switch (checkType) {
                    case 0:
                        userQuery.setSearch(keyword);
                        break;
                    case 1:
                        userQuery.setUserName(keyword);
                        break;
                    case 2:
                        userQuery.setEmail(keyword);
                        break;
                    case 3:
                        userQuery.setPhone(keyword);
                        break;
                    default:
                        userQuery.setSearch(keyword);
                        break;
                }
                Subject subject = SecurityUtils.getSubject();
                if (null != subject.getPrincipal()) {
                    userQuery.setId(getUserId());
                }
                int checkCount = userAccountService.queryCheck(userQuery);
                return (checkCount <= 0);
            }
        } catch (Exception e) {
            logger.error("账号元素占用检测方法异常:", e);
        }
        return false;
    }

    *//**
     * 字符验证码和手机验证码检测
     *
     * @param checkType 1字符验证码,2手机验证码
     * @param code      验证码
     * @return Boolean 对比失败false,对比成功true
     *//*
    @PostMapping("/checkCode/{checkType}")
    @ResponseBody
    public Boolean checkCode(@PathVariable Integer checkType, @RequestParam(required = false, value = "param") String code) {
        boolean verifyBool = false;
        try {
            checkType = checkType == null ? 0 : checkType;
            if (StringUtils.isNotBlank(code)) {
                UserAccountQuery userQuery = new UserAccountQuery();
                switch (checkType) {
                    case 1:
                        //对比验证码
                        verifyBool = VerifyCodeUtil.equals(getVerifyKey(), code.trim());
                        break;
                    case 2:
                        //对比验证码
                        verifyBool = VerifyCodeUtil.equals(getSMSKey(), code.trim());
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception e) {
            logger.error("字符验证码和手机验证码检测方法异常:", e);
        }
        return verifyBool;
    }


    *//**
     * 退出
     *//*
    @GetMapping("/logout")
    public String logout(HttpServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            // session 会销毁，在SessionListener监听session销毁，清理权限缓存
            subject.logout();
            //获取上一页存值
            SavedRequest saveRequest = WebUtils.getSavedRequest(request);
            if (saveRequest != null && StringUtils.isNotBlank(saveRequest.getRequestUrl())) {
                return HtmlConstant.REDIRECT + saveRequest.getRequestUrl();
            }
        }
        return HtmlConstant.REDIRECT + "/";
    }

    *//**
     * 登录检测和跳转
     *//*

    private String isLogin(HttpServletRequest request, String returnUrl) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated() || subject.isRemembered()) {
            return HtmlConstant.REDIRECT + "/user/index";
//            //获取上一页存值
//            SavedRequest saveRequest = WebUtils.getSavedRequest(request);
//            if (saveRequest != null && StringUtils.isNotBlank(saveRequest.getRequestUrl())) {
//                return HtmlConstant.REDIRECT + saveRequest.getRequestUrl();
//            } else {
//                return HtmlConstant.REDIRECT + "/user/index";
//            }
        }
        return returnUrl;
    }

    *//**
     * 跳转地址获取
     *//*
    private String redirectUrl(HttpServletRequest request) {
        //用于登录后跳转到之前网址
        SavedRequest saveRequest = WebUtils.getSavedRequest(request);
        if (saveRequest != null && StringUtils.isNotBlank(saveRequest.getRequestUrl())) {
            return saveRequest.getRequestUrl();
        } else {
            return "/user/index";
        }
    }

    *//**
     * 判断短信验证码
     *
     * @param phone 手机号
     * @param code  验证码
     *//*
    private Result checkSmsCode(String phone, String code) {
        if (StringUtils.isBlank(code)) {
            return R.error(MsgEnum.SMS_CODE_EMPTY.getMsg());
        } else {
            //判断验证码是否正确
            Result contrast = smsUtil.contrast(phone, code);
            //对比失败返回
            if (!contrast.getSuccess()) {
                return contrast;
            } else {
                //删除缓存
                smsUtil.delete(phone);
            }
            return R.success();
        }
    }

    *//**
     * 判断图片验证码
     *
     * @param phone   手机号
     * @param imgCode 验证码
     *//*
    private Result checkImgCode(String sessionId, String imgCode) {
        //非空验证
        if (StringUtils.isBlank(imgCode)) {
            return R.error(MsgEnum.VERIFY_EMPTY.getMsg());
        }
        //获取验证码ID
        boolean exists = redisSessionDAO.exists(sessionId);
        //是否存在
        if (!exists) {
            return R.error(MsgEnum.VERIFY_EMPTY_TIMEOUT.getMsg());
        }
        //获取imgCode
        String redisImgCode = String.valueOf(redisSessionDAO.get(sessionId));
        if (StringUtils.isNotBlank(redisImgCode)) {
            if (redisImgCode.equalsIgnoreCase(imgCode)) {
                return R.success();
            }
        }
        return R.error(MsgEnum.VERIFY_ERROR.getMsg());
    }*/


}
